#ifndef ACE_TCP_ACCEPTOR_IMPL_H
#define ACE_TCP_ACCEPTOR_IMPL_H

#include "ace/Acceptor.h"
#include "ace/Reactor.h"
#include "ace/TP_Reactor.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/INET_Addr.h"
#include "../tcp_acceptor_config.h"

#include <cassert>
#include <string>
namespace vpm
{
	namespace mina
	{
		namespace detail
		{
			template <class T > 
			class AceTcpAcceptorImpl : public ACE_Acceptor<T, ACE_SOCK_ACCEPTOR>
			{
				typedef ACE_Acceptor<T, ACE_SOCK_ACCEPTOR> PARENT; 
				enum 
				{
					TCP_SERVER_DEFAULT_PORT = 8000,
				};
			public:
				AceTcpAcceptorImpl(TcpAcceptorConfig& config, IoHandler & handler): 
                    m_tcpAcceptorConfig(config),m_ioHandler(handler), m_thrdGrpId(-1)
				{
					m_pReactor.reset(new ACE_Reactor( new ACE_TP_Reactor(),1)); 
				}

				virtual ~AceTcpAcceptorImpl()
				{					
				}

				int bind( int port = TCP_SERVER_DEFAULT_PORT, const std::string & host="0.0.0.0")
				{
					//TODO , here it's not safe to used multi thread for reactor. 
					//when not finish the open , other thread will notify the close.  //ACE_REACTOR_THREAD_NUM
					m_thrdGrpId = ACE_Thread_Manager::instance()->spawn_n(1,
                            AceTcpAcceptorImpl::tcp_reactor_event_loop,
                            m_pReactor.get()); 
					if (m_thrdGrpId == -1 )
					{
						return -1; 
					}

					if (!m_tcpAcceptorConfig.is_reuse_address())
					{
						return PARENT::open(ACE_INET_Addr(port,host.c_str()),m_pReactor.get(),0,1,0);     
					}
					else 
					{
						return PARENT::open(ACE_INET_Addr(port,host.c_str()),m_pReactor.get());     
					}		
				}

				int unbind()
				{		
					if (m_thrdGrpId != -1)
					{
						m_pReactor->end_reactor_event_loop(); 
						ACE_Thread_Manager::instance()->wait_grp(m_thrdGrpId); 
					}
					this->close(); 			
					return 0; 
				}

				virtual T *create_handler() 
				{				
					return new T(m_ioHandler,m_tcpAcceptorConfig);		
				}

				virtual int make_svc_handler(T *&h)    
				{
					h = create_handler(); 
					h->reactor(PARENT::reactor()); 		
					return 0; 
				}

				static ACE_THR_FUNC_RETURN tcp_reactor_event_loop(void * pArg)
				{
					assert(pArg != NULL); 
					ACE_Reactor * pReactor = (ACE_Reactor*) pArg; 
					pReactor->owner(ACE_OS::thr_self()); 
					pReactor->run_reactor_event_loop(); 
					return 0; 
				}
			private:
				std::auto_ptr<ACE_Reactor > m_pReactor; 

				TcpAcceptorConfig &m_tcpAcceptorConfig;	
				IoHandler & m_ioHandler;
				int m_thrdGrpId; 
			};

#define  TcpAcceptorImpl AceTcpAcceptorImpl
		}
	}
}



#endif // 



